

觀察資料集與標記CSV檔,發現有下列問題。
1.1 CSV檔中,提供的座標錯誤
top left x出現負值


top left y大於bottom right y


1.2 圖片中鋼胚有2個以上的序號

撰寫程式執行圖片裁切,獲得新資料集,優勢如下。
2.1 鋼胚序號占整張圖片比例小,只裁切序號位置做為資料集,可提高待辨識物件的占比。
裁切前

裁切後

2.2 篩除有2個以上序號的圖片與CSV檔錯誤標記的圖片
資料夾格式
1.1 datasets_ocr

1.2 public_training_data

流程與Python函式
2.1 圖檔操作
def cv_imread(image_path):
    image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), -1)
    image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
    return image
def show_img(name, image):
    cv2.imshow(name, image)
    cv2.waitKey(0)
def cv_save(image, result_path):
    cv2.imencode('.jpg', image)[1].tofile(result_path)   
2.2 讀取CSV檔獲得裁切的座標與標籤
def bbox(df_path, image_path):
    df = pd.read_csv(df_path)
    image_id = image_path.split('/')[-1][:-4]
    xmin = df[df['filename'] == image_id]['top left x']
    xmax = df[df['filename'] == image_id]['bottom right x']
    ymin = df[df['filename'] == image_id]['top left y']
    ymax = df[df['filename'] == image_id]['bottom right y']
    label = df[df['filename'] == image_id]['label']
    box = {'xmin': int(xmin) - 28, 'xmax': int(xmax) + 28,
           'ymin': int(ymin) - 40, 'ymax': int(ymax) + 40}
    return box, label.values[0]
2.3 接收座標進行圖片裁切
def cut_img(image, box):
    result = image[box['ymin']:box['ymax'], box['xmin']:box['xmax']]
    return result
完整程式碼
import numpy as np
import pandas as pd
import cv2
import os
def cv_imread(image_path):
    image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), -1)
    image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
    return image
def show_img(name, image):
    cv2.imshow(name, image)
    cv2.waitKey(0)
def cv_save(image, result_path):
    cv2.imencode('.jpg', image)[1].tofile(result_path)
def bbox(df_path, image_path):
    df = pd.read_csv(df_path)
    image_id = image_path.split('/')[-1][:-4]
    xmin = df[df['filename'] == image_id]['top left x']
    xmax = df[df['filename'] == image_id]['bottom right x']
    ymin = df[df['filename'] == image_id]['top left y']
    ymax = df[df['filename'] == image_id]['bottom right y']
    label = df[df['filename'] == image_id]['label']
    box = {'xmin': int(xmin) - 28, 'xmax': int(xmax) + 28,
           'ymin': int(ymin) - 40, 'ymax': int(ymax) + 40}
    return box, label.values[0]
def cut_img(image, box):
    result = image[box['ymin']:box['ymax'], box['xmin']:box['xmax']]
    return result
if __name__ == '__main__':
    df_path = './public_training_data.csv'
    source_path = './public_training_data/'
    images = os.listdir('./public_training_data/')
    image_path = [source_path+i for i in images]
    go_path = './data_go/'
    ng_path = './data_ng/'
    if not os.path.exists(go_path):
        os.makedirs(go_path)
    if not os.path.exists(ng_path):
        os.makedirs(ng_path)
    n = 1
    for i in image_path:
        print('※ 讀取第 {} 張圖'.format(n))
        box, label = bbox(df_path, i)
        label = label + '.jpg'
        image = cv_imread(i)
        # show_img('image', image)
        
        # 用來篩除異常圖片或異常標記
        try:
            result = cut_img(image, box)
            # show_img('result', result)
            result_path = go_path + label
            cv_save(result, result_path)
            print('{} 通過篩選'.format(result_path.split('/')[-1]))
            print('='*40)
        except:
            result_path = ng_path + label
            cv_save(image, result_path)
            print('{} 未通過篩選'.format(result_path.split('/')[-1]))
            print('=' * 40)
        n += 1
    print('※ 程式執行完畢')
執行程式
4.1 執行結果

4.2 通過篩選與裁切的圖片(以鋼胚序號作為檔名)

4.3 被篩除的圖片(以鋼胚序號作為檔名)

讓我們繼續看下去...
有機會全部整理成一篇文章嗎?
你好,近期工作忙碌,現在才看到留言。目前暫時沒有計畫重新編撰文章。需要詳細、連貫的說明,歡迎私訊我。謝謝。